/**
*  \file    li_ion.h
*
*  \brief   Lithium Ion Project
*
*  \author  Thomas Wenzel <thomas.wenzel@linde-mh.de>
*
*/

#ifndef LI_ION_H_INCLUDED
#define LI_ION_H_INCLUDED

/*================================================[ public includes  ]================================================*/
#include "../cfg/prj.h"                           /* via ../pal/types.h, e.g. RC, .. */
//#include "../cfg/vin_cfg.h"                       /* VIN_STRING_SIZE, .. */

/*================================================[ public defines   ]================================================*/
#define EQU_BATT_TYPE_INVALID                 (0)
#define EQU_BATT_TYPE_LEAD_ACID               (1)
#define EQU_BATT_TYPE_LI_ION                  (2)
//#define EQU_LI_ION_INVALID_SERIAL_NUMBER      (U32_MAX)

// Workaround bis korrekte Batterie-Serien-Nummer verf�gbar
#define EQU_LI_ION_INVALID_SERIAL_NUMBER      (0xAFFEAFFE)

/* States: -> s16State */
#define EQU_LI_ION_ERROR                          (-1)
#define EQU_LI_ION_INIT                           (0)
#define EQU_IS_LEAD_ACID_BATTERY                  (1)
#define EQU_LI_ION_AUTHENT_START                  (2)
#define EQU_LI_ION_IDENTIFIED                     (3)
#define EQU_LI_ION_WAIT_FOR_BATT_READY            (4)
#define EQU_LI_ION_CHECK_VOLTAGE                  (5)
#define EQU_IS_LI_ION_BATTERY                     (6)

#define EQU_LI_ION_SDO_SEND_BATTERY_VOLTAGE       (7)
#define EQU_LI_ION_SDO_WAIT_BATTERY_VOLTAGE       (8)
#define EQU_LI_ION_SDO_BATTERY_VOLTAGE_FINISHED   (9)
#define EQU_LI_ION_SDO_SEND_VIN                   (10)
#define EQU_LI_ION_SDO_WAIT_VIN                   (11)
#define EQU_LI_ION_SDO_VIN_FINISHED               (12)
#define EQU_LI_ION_SDO_SEND_CAN_SCHEME            (13)
#define EQU_LI_ION_SDO_WAIT_CAN_SCHEME            (14)
#define EQU_LI_ION_SDO_CAN_SCHEME_FINISHED        (15)
#define EQU_LI_ION_SDO_REQUEST_BATTERY_SERIAL_NR  (16)
#define EQU_LI_ION_SDO_WAIT_BATTERY_SERIAL_NR     (17)
#define EQU_LI_ION_SDO_BATTERY_SERIAL_NR_FINISHED (18)
#define EQU_LI_ION_SDO_REQUEST_BATTERY_ENERGY     (19)
#define EQU_LI_ION_SDO_WAIT_BATTERY_ENERGY        (20)
#define EQU_LI_ION_SDO_BATTERY_ENERGY_FINISHED    (21)

#define EQU_LI_ION_SEND_MODULE_CTRL               (22)
#define EQU_LI_ION_MODULE_CTRL_ACK                (23)

#define EQU_LI_ION_SDO_SEND_BATTERY_ON            (24)
#define EQU_LI_ION_SDO_WAIT_BATTERY_ON            (25)
#define EQU_LI_ION_SDO_BATTERY_ON_FINISHED        (26)

#define EQU_LI_ION_FINISHED                       (99)

/* States: -> s16Error */
#define EQU_LI_ION_OK                         (0)
#define EQU_LI_ION_ERROR_001                  (1)              /* :K41 was < 10.0V, but no Heartbeat within 200ms from BMS-System */
#define EQU_LI_ION_ERROR_002                  (2)              /* Wait for battery ready */
#define EQU_LI_ION_ERROR_004                  (4)              /* Battery turned on, but :K41 stays low (< 10V)                   */
#define EQU_LI_ION_ERROR_005                  (5)              /* SDO-download timeout (>100ms) / Battery voltage                 */
#define EQU_LI_ION_ERROR_006                  (6)              /* SDO-retries (>2) exceeded / Battery voltage                     */
#define EQU_LI_ION_ERROR_007                  (7)              /* Error VIN: Invalid start-character                              */
#define EQU_LI_ION_ERROR_008                  (8)              /* SDO-download timeout (>100ms) / VIN                             */
#define EQU_LI_ION_ERROR_009                  (9)              /* SDO-retries (>2) exceeded / VIN                                 */
#define EQU_LI_ION_ERROR_010                  (10)             /* SDO-download timeout (>100ms) / CAN-scheme                      */
#define EQU_LI_ION_ERROR_011                  (11)             /* SDO-retries (>2) exceeded / CAN-scheme                          */
#define EQU_LI_ION_ERROR_012                  (12)             /* SDO-uploadload timeout (>100ms) / Battery-Serial-Nr             */
#define EQU_LI_ION_ERROR_013                  (13)             /* SDO-retries (>2) exceeded   / Battery-Serial-Nr                 */
#define EQU_LI_ION_ERROR_014                  (14)             /* Invalid Battery-Serial-Nr                                       */
#define EQU_LI_ION_ERROR_015                  (15)             /* SDO-uploadload timeout (>100ms) / Battery-Energy                */
#define EQU_LI_ION_ERROR_016                  (16)             /* SDO-retries (>2) exceeded   / Battery-Energy                    */
#define EQU_LI_ION_ERROR_017                  (17)             /* Invalid Battery-Energy                                          */
#define EQU_LI_ION_ERROR_018                  (18)             /* ModuleCtrl not sent within 50ms                                 */
#define EQU_LI_ION_ERROR_019                  (19)             /* SDO-download timeout (>100ms) / Battery on                      */
#define EQU_LI_ION_ERROR_020                  (20)             /* SDO-retries (>2) exceeded / Battery on                          */
#define EQU_LI_ION_ERROR_021                  (21)             /* PDO Lost                                                        */

#define EQU_LI_ION_20ms                       (2)              /* 2   = 2 *10ms  = 20ms  */
#define EQU_LI_ION_50ms                       (5)              /* 5   = 5 *10ms  = 50ms  */
#define EQU_LI_ION_80ms                       (8)              /* 8   = 8 *10ms  = 80ms  */
#define EQU_LI_ION_100ms                      (10)             /* 10  = 10*10ms  = 100ms */
#define EQU_LI_ION_150ms                      (15)             /* 15  = 15*10ms  = 150ms */
#define EQU_LI_ION_200ms                      (20)             /* 20  = 20*10ms  = 200ms */
#define EQU_LI_ION_500ms                      (50)             /* 50  = 50*10ms  = 500ms */
#define EQU_LI_ION_1000ms                     (100)            /* 100 = 100*10ms = 1000ms */
#define EQU_LI_ION_5000ms                     (500)            /* 500 = 500*10ms = 5000ms */

#define STATUS_LI_ION_BATTERY_INVALID_0       (0x00)           /* see DOC0016987 ... */
#define STATUS_LI_ION_BATTERY_IDLE            (0x01)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_SELFTEST        (0x02)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_READY           (0x04)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_ERROR_ANALYSIS  (0x08)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_INITIAL_OP      (0x0F)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_DRIVING         (0x10)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_SERVICE_DRIVE   (0x12)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_CHARGING        (0x20)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_SERVICE_CHARGE  (0x22)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_EMERGENCY       (0x48)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_SERVICE_ERROR   (0x82)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_ERROR           (0x88)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_MANUFACT_DIAG   (0x8F)           /* Bitmask */
#define STATUS_LI_ION_BATTERY_INVALID_1       (0xFF)

#define EQU_LI_ION_CAN_HEARTBEAT              (1)              /* Heartbeat Info from BMS */
#define EQU_LI_ION_CAN_PDO1                   (2)              /* PDO1: Data from BMS (PDO 0x18D Bytes 0 - 7) see CAN0_38x.dbc */
#define EQU_LI_ION_CAN_PDO2                   (3)              /* PDO2: Data from BMS (PDO 0x28D Bytes 0 - 7) see CAN0_38x.dbc */
#define EQU_LI_ION_CAN_PDO4                   (4)              /* PDO4: Data from BMS (PDO 0x48D Bytes 0 - 7) see CAN0_38x.dbc */
#define EQU_LI_ION_CAN_PDO5                   (5)              /* PDO5: Data from BMS (PDO 0x301 Bytes 0 - 7) see CAN0_38x.dbc */

#define VIN_STRING_SIZE U8_CONST( 12 )

/*================================================[ public datatypes ]================================================*/
/* I/O for lithium-ion-battery module                                                                                 */
typedef struct
{
   /* ======= */
   /* System: */
   /* ======= */
   S16 s16State;                                  /* SYMTAB name='li_ion::sLiIon.s16State',
                                                            unit='-',
                                                            label='li-ion state-machine' ,
                                                            type='S16L', min=-100, max=100, slope=1 */
   S16 s16Counter;                                /* State-Counter */
   S16 s16Error;                                  /* SYMTAB name='li_ion::sLiIon.s16Error',
                                                            unit='-',
                                                            label='li-ion startup errors' ,
                                                            type='S16L', min=-100, max=100, slope=1 */
   S16 s16SDORetry;                               /* Retries-Variable */

   /* ======= */
   /* Inputs: */
   /* ======= */

   /* Analog: */
   F32 f32BatteryVolt_K41;                        /* SYMTAB name='li_ion::sLiIon.f32BatteryVolt_K41'  ,
                                                            unit='V'    ,
                                                            label='(:41K) Battery voltage' ,
                                                            type='F32L'  ,  min=-1      , max=120     , slope=1 */
   F32 f32CodeLiIon;                              /* SYMTAB name='li_ion::sLiIon.f32CodeLiIon'  ,
                                                            unit='V'    ,
                                                            label='(:84K) Codepin lithium-ion-battery fitted' ,
                                                            type='F32L'  ,  min=-1      , max=15      , slope=1 */
   U8  in_bLiIon;

   /* CAN: */
   /* 0x70D: Heartbeat */
   U8  CAN_LiIoBMSB_State;                        /* CAN: Heartbeat-Info from Battery-Managment-System                                   */

   /* 0x18D: PDO1 */
   F32 CAN_LiIoBMS_BatteryCurrent_A;              /* CAN: PDO1 (0x18D) Byte 0-2: Battery-Current[A]                                      */
   F32 CAN_LiIoBMS_BatteryVoltage_V;              /* CAN: PDO1 (0x18D) Byte 3-5: Battery-Voltage[V]                                      */
   U8  CAN_LiIoBMS_BatteryStatus;                 /* CAN: PDO1 (0x18D) Byte 6:   Status of Lithium-Ion Battery                           */
   U8  CAN_LiIoBMS_StateOfHealth;                 /* CAN: PDO1 (0x18D) Byte 7:   State of Health [%]                                     */

   /* 0x28D: PDO2 */
   F32 CAN_LiIoBMS_MaxChargeCurrent_2sec_A;       /* CAN: PDO2 (0x28D) Byte 0-1: LiIo battery max. short-term charge current [A]         */
   F32 CAN_LiIoBMS_MaxDischargeCurrent_2sec_A;    /* CAN: PDO2 (0x28D) Byte 2-3: LiIo battery max. short-term discharge current [A]      */
   F32 CAN_LiIoBMS_MaxChargeCurrent_100sec_A;     /* CAN: PDO2 (0x28D) Byte 4-5: LiIo battery max. short-term charge current [A]         */
   F32 CAN_LiIoBMS_MaxDischargeCurrent_100sec_A;  /* CAN: PDO2 (0x28D) Byte 6-7: LiIo battery max. short-term discharge current [A]      */

   /* 0x48D: PDO4 */
   F32 CAN_LiIoBMS_MinDischargeVoltage_V;         /* CAN: PDO4 (0x48D) Byte 0-2: LiIo battery min. discharge voltage [V]                 */
   F32 CAN_LiIoBMS_MaxChargeVoltage_V;            /* CAN: PDO4 (0x48D) Byte 3-5: LiIo battery max. charging voltage [V]                  */
   U8  CAN_LiIoBMS_SOCwithoutSOH;                 /* CAN: PDO4 (0x48D) Byte 6:   LiIo battery charge (battery health not considered) [%] */
   U8  CAN_LiIoBMS_SOCwithSOH;                    /* CAN: PDO4 (0x48D) Byte 7:   LiIo battery charge (battery health considered) [%]     */

   /* 0x301: PDO5 */
   F32 CAN_LiIoBMS_OutputVoltage_V;               /* CAN: PDO5 (0x301) Byte 0-2: LiIo battery output voltage [V]                         */
   U32 CAN_LiIoBMS_MaxDischargePower_2sec;        /* CAN: PDO5 (0x301) Byte 3-4: LiIo battery max. short-term discharge power [W]        */
   U32 CAN_LiIoBMS_MaxChargePower_2sec;           /* CAN: PDO5 (0x301) Byte 5-6: LiIo battery max. short-term charging power [W]         */

   /* SDO's */
   U32 CAN_BatterySerialNo;                       /* CAN: Battery-Serial-Number 05.09.2014/TW -> U32                                     */
   U32 CAN_BatteryEnergy;                         /* CAN: Battery's energy content in [Wh]                                               */
   U8  CAN_vin[VIN_STRING_SIZE];                  /* CAN: Truck's vehicle identification number                                          */

   /* ======== */
   /* Outputs: */
   /* ======== */
   S16 s16BatteryType;                            /* Typ der angeschlossenen und authentifizierten Batterie */

   /* =================== */
   /* Remaining Work-Time */
   /* =================== */
   BO  bInitCurrentVoltage;
   F32 f32RWTActualEnergy_Wh;                     /* SYMTAB name='li_ion::sLiIon.f32RWTActualEnergy_Wh'  ,
                                                            unit='Wh'    ,
                                                            label='Actual lithium-ion-battery energy in Wh' ,
                                                            type='F32L'  ,  min=-1      , max=200000      , slope=1 */
   F32 f32BattCurrentAvrg;                        /* SYMTAB name='li_ion::sLiIon.f32BattCurrentAvrg'  ,
                                                            unit='A'    ,
                                                            label='Averaged lithium-ion-battery current' ,
                                                            type='F32L'  ,  min=-1000   , max=1000     , slope=1 */
   F32 f32BattVoltAvrg;                           /* SYMTAB name='li_ion::sLiIon.f32BattVoltAvrg'  ,
                                                            unit='V'    ,
                                                            label='Averaged lithium-ion-battery voltage' ,
                                                            type='F32L'  ,  min=-150   , max=150     , slope=1 */
   F32 f32BattCurrentAvrg_F;                      /* SYMTAB name='li_ion::sLiIon.f32BattCurrentAvrg_F'  ,
                                                            unit='A'    ,
                                                            label='Averaged plus filtered lithium-ion-battery current' ,
                                                            type='F32L'  ,  min=-1000  , max=1000    , slope=1 */
   F32 f32BattVoltAvrg_F;                         /* SYMTAB name='li_ion::sLiIon.f32BattVoltAvrg_F'  ,
                                                            unit='V'    ,
                                                            label='Averaged plus filtered lithium-ion-battery voltage' ,
                                                            type='F32L'  ,  min=-150   , max=150     , slope=1 */
   F32 f32RemWorkTime;                            /* SYMTAB name='li_ion::sLiIon.f32RemWorkTime'  ,
                                                            unit='s'    ,
                                                            label='Lithium-ion-battery remaining work-time' ,
                                                            type='F32L'  ,  min=0  , max=40000    , slope=1 */
   F32 f32RemWorkTimeFilt;                        /* SYMTAB name='li_ion::sLiIon.f32RemWorkTime'  ,
                                                            unit='s'    ,
                                                            label='Lithium-ion-battery filtered remaining work-time' ,
                                                            type='F32L'  ,  min=0  , max=40000    , slope=1 */

   /* ======================= */
   /* Shocklevel 2 Managment: */
   /* ======================= */
   U16 u16DTC_Can[4];

   /* =========== */
   /* Abregelung: */
   /* =========== */
   F32 CAN_LiIoBMS_MaxDischargeCurrent_2sec_F;    /* [A] filtered CAN-signal to avoid strong current drops */

} LITHIUM_ION_IO ;

/* SPECS-Entries for lithium-ion-battery module                                                                                 */
typedef struct
{
   F32 MinDischargeCurrent;                       /* [A] Minimaler Batterie-Entladestrom (2s-Prognose) bei dem das Fahrzeug gestoppt wird       */
   S16 ChargeCurrent_Start_PRed;                  /* [A] Batterie-R�ckspeisestrom (2s-Prognose) ab dem die Bremskraft linear reduziert wird     */
   S16 ChargeCurrent_End_PRed;                    /* [A] Batterie-R�ckspeisestrom (2s-Prognose) bis zu dem die Bremskraft linear reduziert wird */
   S16 DisChargeCurrent_Start_PRed;               /* [A] Batterie-Entladestrom (2s-Prognose) ab dem die Fahrleistung linear reduziert wird      */
   S16 DisChargeCurrent_End_PRed;                 /* [A] Batterie-Entladestrom (2s-Prognose) bis zu dem die Fahrleistung linear reduziert wird  */
   S16 AvrgCurrentRemWorkTime;                    /* [A] Mittlerer Durchschnittsentladestrom zur Initialisierung Restfahrzeitberechnung         */
} LITHIUM_ION_SPECS ;

/*================================================[ public variables ]================================================*/
extern LITHIUM_ION_IO sLiIon;
extern F32 ba_qBat_rpReqLiIon;
extern U8 CounterState;/*guo*/
extern U8 MessageLostCounter_PDO1;
extern U8 MessageLostCounter_PDO2;
extern U8 MessageLostCounter_PDO4;
extern U8 MessageLostCounter_PDO5;
/*================================================[ public functions ]================================================*/

/** Initialization.
*
*  Initialize the lithium-ion module.
*
*  \return Always RC_SUCCESS.
*/
RC app_li_ion_initialize( VO );

/** 10ms service
*
*  run-time calling of function from 10ms-task
*
*  \return Always RC_SUCCESS.
*/
RC app_li_ion_10ms( VO );

/** CAN-Receive Function
*
*  fill lithium-ion-module with BMS-system info
*
*  \return Always RC_SUCCESS.
*/
VO vdLiIon_CanGetData(S16 s16Mode);

VO li_ion_callback(RC code, U32 ret, U32 sdo_abort_code);

/** Lithium-Ion SOC transformation
*
*  \return Always transformed SOC, that display works fine
*/
F32 f32TransformLiIonSOC(U8 u8SOCwithSOH);

/** Lithium-Ion SOC transformation
*
*  \return re-calculated remaining work-time in [s]
*/
F32 f32CalcRemainWorkTime_LiIon(U8  u8SOC,
                                F32 f32RunTime);

/** Lithium-Ion power-reduction with low discharge-current
*
*  \return re-calculated percentage-factor passed to tractive-force-power-reduction
*/
F32 f32LiIon_DischargeCurrent_Down(
   F32   q      /* actual signal value [A] */
,  F32   q1     /* current threshold [A] for start of power reduction (100% power)  */
,  F32   q0     /* current threshold [A] for end   of power reduction (  0% power)  */
,  S16   s16Cmd /* 1: use filtered input */
) ;

/** Lithium-Ion configuration
*
*  \return TRUE , when lithium-ion-battery-managment-system is detected
*          FALSE, else
*/
S16 IsLithiumIonBattery(VO) ;

/** Lithium-Ion configuration
*
*  \return TRUE , when boot-up finised and either lead-acid or lithium-ion-battery is detected
*          FALSE, else
*/
S16 IsLiIonBootUpFinished(VO) ;


VO MessageCounterStateMachine(VO); /* guo */

/* LI ION BATTERY */
extern F32 GetBatterSoc(void);

extern U32 GetBatterVoltage(void);

extern F32 GetBatterCurrent(void);

extern F32 GetBatterMaxChargeCurrent_2sec(void);

extern F32 GetBatterMaxDischargeCurrent_2sec(void);

extern F32 GetBatterMaxChargeCurrent_100sec(void);

extern F32 GetBatterMaxDischargeCurrent_100sec(void);

extern F32 GetBatteRWTActualEnergy_Wh(void);

/*====================================================================================================================*/

#endif
/***********************************************************************************************************************
*                             Copyright 2014 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
